From 7fd6d97f2457baddd8897eed7c1a39a3475155c8 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild.aw" Date: Mon, 3 Jul 2006 08:53:02 -0600 Subject: [PATCH] [IA64] allow vcpu to move between pcpus Signed-off-by: Isaku Yamahata --- xen/arch/ia64/xen/domain.c | 30 ++++++++++++++++++++++++++++++ xen/arch/ia64/xen/vhpt.c | 2 +- xen/include/asm-ia64/domain.h | 7 +++++++ xen/include/asm-ia64/vhpt.h | 1 + 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index f6b39d7dba..ec8f860196 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -92,6 +92,29 @@ DEFINE_PER_CPU(int *, current_psr_ic_addr); #include +static void flush_vtlb_for_context_switch(struct vcpu* vcpu) +{ + int last_vcpu_id = + vcpu->domain->arch.last_vcpu[smp_processor_id()].vcpu_id; + + if (is_idle_domain(vcpu->domain) || last_vcpu_id == vcpu->vcpu_id) + return; + vcpu->domain->arch.last_vcpu[smp_processor_id()].vcpu_id = + vcpu->vcpu_id; + if (last_vcpu_id == INVALID_VCPU_ID) + return; + + // if the vTLB implementation was changed, + // the followings must be updated either. + if (VMX_DOMAIN(vcpu)) { + // currently vTLB for vt-i domian is per vcpu. + // so any flushing isn't needed. + } else { + vhpt_flush(); + } + local_flush_tlb_all(); +} + void schedule_tail(struct vcpu *prev) { extern char ia64_ivt; @@ -110,6 +133,7 @@ void schedule_tail(struct vcpu *prev) __ia64_per_cpu_var(current_psr_ic_addr) = (int *) (current->domain->arch.shared_info_va + XSI_PSR_IC_OFS); } + flush_vtlb_for_context_switch(current); } void context_switch(struct vcpu *prev, struct vcpu *next) @@ -175,6 +199,7 @@ if (!i--) { i = 1000000; printk("+"); } __ia64_per_cpu_var(current_psr_ic_addr) = NULL; } } + flush_vtlb_for_context_switch(current); local_irq_restore(spsr); context_saved(prev); } @@ -309,9 +334,14 @@ static void init_switch_stack(struct vcpu *v) int arch_domain_create(struct domain *d) { + int i; + // the following will eventually need to be negotiated dynamically d->arch.shared_info_va = DEFAULT_SHAREDINFO_ADDR; d->arch.breakimm = 0x1000; + for (i = 0; i < NR_CPUS; i++) { + d->arch.last_vcpu[i].vcpu_id = INVALID_VCPU_ID; + } if (is_idle_domain(d)) return 0; diff --git a/xen/arch/ia64/xen/vhpt.c b/xen/arch/ia64/xen/vhpt.c index 3fe48facf7..895e8bc0fe 100644 --- a/xen/arch/ia64/xen/vhpt.c +++ b/xen/arch/ia64/xen/vhpt.c @@ -23,7 +23,7 @@ extern long running_on_sim; DEFINE_PER_CPU (unsigned long, vhpt_paddr); DEFINE_PER_CPU (unsigned long, vhpt_pend); -static void vhpt_flush(void) +void vhpt_flush(void) { struct vhpt_lf_entry *v = __va(__ia64_per_cpu_var(vhpt_paddr)); int i; diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index d244e055e8..2f4b740edd 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -58,6 +58,11 @@ struct mm_struct { // atomic_t mm_users; /* How many users with user space? */ }; +struct last_vcpu { +#define INVALID_VCPU_ID INT_MAX + int vcpu_id; +} ____cacheline_aligned_in_smp; + struct arch_domain { struct mm_struct mm; unsigned long metaphysical_rr0; @@ -101,6 +106,8 @@ struct arch_domain { void *efi_runtime; /* Metaphysical address to fpswa_interface_t in domain firmware memory is set. */ void *fpswa_inf; + + struct last_vcpu last_vcpu[NR_CPUS]; }; #define INT_ENABLE_OFFSET(v) \ (sizeof(vcpu_info_t) * (v)->vcpu_id + \ diff --git a/xen/include/asm-ia64/vhpt.h b/xen/include/asm-ia64/vhpt.h index 8823f1b56e..6836ccafd1 100644 --- a/xen/include/asm-ia64/vhpt.h +++ b/xen/include/asm-ia64/vhpt.h @@ -42,6 +42,7 @@ extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte, unsigned long logps); extern void vhpt_insert (unsigned long vadr, unsigned long pte, unsigned long logps); +void vhpt_flush(void); /* Currently the VHPT is allocated per CPU. */ DECLARE_PER_CPU (unsigned long, vhpt_paddr); -- 2.30.2